package durak.client.view;

import java.awt.AlphaComposite;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Image;
import java.awt.Insets;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.image.BufferedImage;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import javax.swing.ImageIcon;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.border.BevelBorder;

import durak.client.control.ICardListener;
import durak.common.model.Card;
import durak.common.model.CommonPlayerData;
import durak.common.model.GameTableState;

public class GamingTableView extends DurakPanel implements MouseListener {
	
	GameTableState	tableState;
	ICardListener emptyListener;
	DurakPanel		cardsOntablePanel;
	DurakPanel		leftPlayerView;
	DurakPanel		topPlayerView;
	DurakPanel		rightPlayerView;
	DurakPanel		deckView;
	JLabel		smallPlayerIcon;
	
	public GamingTableView() {
		URL fileLocation = LoginToDurak.class.getResource("/durak/resources/images/Player.png");
		smallPlayerIcon = new JLabel(new ImageIcon(fileLocation));
		smallPlayerIcon.setSize(40, 40);
		//setBackground(new Color(0, 102, 0));
		setBorder(new BevelBorder(BevelBorder.LOWERED));
		setLayout(new BorderLayout());
		
		GridBagLayout gridBagLayout = new GridBagLayout();
        gridBagLayout.columnWidths = new int[]{0};
        gridBagLayout.rowHeights = new int[]{0};
        gridBagLayout.columnWeights = new double[]{Double.MIN_VALUE};
        gridBagLayout.rowWeights = new double[]{Double.MIN_VALUE};
        cardsOntablePanel = new DurakPanel();
        cardsOntablePanel.setLayout(gridBagLayout);
		add(cardsOntablePanel, BorderLayout.CENTER);
		
		leftPlayerView = new DurakPanel();
		leftPlayerView.setName("leftPlayerView");
		leftPlayerView.setLayout(new FlowLayout(FlowLayout.LEFT));
		add(leftPlayerView, BorderLayout.WEST);
		
		topPlayerView = new DurakPanel();
		topPlayerView.setName("topPlayerView");
		topPlayerView.setLayout(new FlowLayout(FlowLayout.CENTER));
		add(topPlayerView, BorderLayout.NORTH);
		
		rightPlayerView = new DurakPanel();
		rightPlayerView.setName("rightPlayerView");
		rightPlayerView.setLayout(new FlowLayout(FlowLayout.RIGHT));
		add(rightPlayerView, BorderLayout.EAST);
		
		deckView = new DurakPanel();
		deckView.setName("deckView");
		deckView.setLayout(new FlowLayout(FlowLayout.RIGHT));
		add(deckView, BorderLayout.SOUTH);
		
		emptyListener = new ICardListener() {public void cardClickedAction(Card card) {}};
	}

	@Override
	public void mouseClicked(MouseEvent arg0) {
		// TODO Auto-generated method stub

	}

	@Override
	public void mouseEntered(MouseEvent arg0) {
		// TODO Auto-generated method stub

	}

	@Override
	public void mouseExited(MouseEvent arg0) {
		// TODO Auto-generated method stub

	}

	@Override
	public void mousePressed(MouseEvent arg0) {
		// TODO Auto-generated method stub

	}

	@Override
	public void mouseReleased(MouseEvent arg0) {
		// TODO Auto-generated method stub

	}

	public void showGamingTable(String myName, GameTableState gameState, ICardListener cardListener, Card selectedCard) {
		this.tableState = gameState;
		ArrayList<JPanel> playerPanels = new ArrayList<JPanel>();
		List<CommonPlayerData> playersData = gameState.getPlayers();
		int myIndex = 0;
		String roleString = new String("");
		
		for (CommonPlayerData commonPlayerData : playersData) {
			if(commonPlayerData.getName() != null && commonPlayerData.getName().equals(myName)) {
				myIndex = playersData.indexOf(commonPlayerData);
				break;
			}
		}
		Collections.rotate(playersData, playersData.size() - myIndex);
		
		showCardsOnTable(cardListener, selectedCard);
		showDeckAndKozar(gameState.getDeckSize());
		
		if(gameState.getPlayers().size() == 4) {
			playerPanels.add(leftPlayerView);
			playerPanels.add(topPlayerView);
			playerPanels.add(rightPlayerView);
		} else if(gameState.getPlayers().size() == 3) {
			playerPanels.add(leftPlayerView);			
			playerPanels.add(rightPlayerView);
		} else {
			playerPanels.add(topPlayerView);
		}
		
		
		for (int i = 1; i < playersData.size(); i++) {
			final CommonPlayerData playerData = playersData.get(i);
			roleString= new String("");
			playerPanels.get(i-1).removeAll();
			playerPanels.get(i-1).add(new JLabel(smallPlayerIcon.getIcon()));
			if (playerData.getName()==tableState.getCurrentAttacker())
				roleString = new String("Attacking:  ");
			else if (playerData.getName()==tableState.getCurrentDefender())
				roleString = new String("Defending:  ");
			else if(playerData.isLeftTheGame())
				roleString = new String("Left the game  ");
			JLabel playerName = new JLabel(roleString +" "+ playerData.getName());
			playerName.setForeground(Color.WHITE);
			playerPanels.get(i-1).add(playerName);
			JLabel playersHand = new JLabel(ImageUtils.getImageIconScaled("BACK_OF_CARD.jpg", 27, 40)) {
				@Override
				protected void paintComponent(Graphics g) {
					// TODO Auto-generated method stub
					super.paintComponent(g);
					g.drawString(Integer.toString(playerData.getNumOfCardsInHand()), 5, 25);
				}
			};
			playersHand.setForeground(Color.YELLOW);
			playersHand.setFont(new Font("Courier New", Font.BOLD, 20));
			playerPanels.get(i-1).add(playersHand);
		}
		
		
				
		revalidate();
		repaint();
	}

	private void showDeckAndKozar(int deckSize) {
		deckView.removeAll();
		if (deckSize > 0) {
			ImageIcon backOfCardImage = new ImageIcon(LoginToDurak.class.getResource("/durak/resources/images/BACK_OF_CARD.jpg"));
			ImageIcon backgroundImage = new ImageIcon(getClass().getResource("/durak/resources/images/CardTable.jpg"));
			CardLabel kozarCardLabel = new CardLabel(tableState.getKozar(), emptyListener, 90);

			int height = kozarCardLabel.getWidth() > kozarCardLabel.getHeight() ? kozarCardLabel.getWidth() : kozarCardLabel.getHeight();
			BufferedImage bfImage = new BufferedImage(kozarCardLabel.getWidth() + kozarCardLabel.getHeight(), height + height / 2, BufferedImage.TYPE_INT_RGB);
			Graphics2D g2 = bfImage.createGraphics();
			g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER));
			g2.drawImage(backgroundImage.getImage(), 0, 0, bfImage.getWidth(), bfImage.getHeight(), deckView);
			g2.drawImage(kozarCardLabel.getImage(), 0, kozarCardLabel.getWidth() / 2 - kozarCardLabel.getHeight() / 2, deckView);
			g2.drawImage(backOfCardImage.getImage(), 50, 0, deckView);
			g2.drawImage(backOfCardImage.getImage(), 55, 0, deckView);
			g2.drawImage(backOfCardImage.getImage(), 60, 0, deckView);
			JLabel tempLabel = new JLabel(new ImageIcon(bfImage.getScaledInstance(bfImage.getWidth(), bfImage.getHeight(), Image.SCALE_SMOOTH)));
			deckView.add(tempLabel);
		}
	}

	/**
	 * @param cardListener
	 * @param selectedCard
	 */
	private void showCardsOnTable(ICardListener cardListener, Card selectedCard) {
		ICardListener lCarListener;
		int gridColumn = 0;
		
		cardsOntablePanel.removeAll();
				
		for (int i = 0; i < tableState.getCardsOnTheTable().getAttackCards().size(); i++) {
			Card card = tableState.getCardsOnTheTable().getAttackCards().get(i);
			lCarListener = cardListener;
			
			if( i < tableState.getCardsOnTheTable().getDefendCards().size() && tableState.getCardsOnTheTable().getDefendCards().getCardByLocation(i) !=null) {
				lCarListener = emptyListener;
			}
			
			CardLabel cardLabel = new CardLabel(card, lCarListener);
			GridBagConstraints cardConstrain = new GridBagConstraints();
			cardConstrain.insets = new Insets(5, 5, 5, 5);
			cardConstrain.gridx = gridColumn++;
			cardConstrain.gridy = 2;
			if(selectedCard != null && card.equals(selectedCard)) {
				cardLabel.setBorder(new BevelBorder(BevelBorder.LOWERED));
			} else {
				cardLabel.setBorder(new BevelBorder(BevelBorder.RAISED));
			}
			cardsOntablePanel.add(cardLabel, cardConstrain);
		}
	
		gridColumn = 0;
		for(Card card : tableState.getCardsOnTheTable().getDefendCards()) {
			CardLabel cardLabel = new CardLabel(card, emptyListener);
			GridBagConstraints cardConstrain = new GridBagConstraints();
			cardConstrain.insets = new Insets(5, 5, 5, 5);
			cardConstrain.gridx = gridColumn++;
			cardConstrain.gridy = 4;
			if(selectedCard != null && card.equals(selectedCard)) {
				cardLabel.setBorder(new BevelBorder(BevelBorder.LOWERED));
			} else {
				cardLabel.setBorder(new BevelBorder(BevelBorder.RAISED));
			}
			cardsOntablePanel.add(cardLabel, cardConstrain);
		}
	}
}
